/**
 * Created by fanyongsheng on 2017/7/10.
 */
/**********************************************************/
/*                                                        */
/*                       anychatsdk obj                    */
/*                                                        */
/**********************************************************/

var webrtc = require('./webrtc.js');
var heartbeat_module = require('./heartbeat.ts');
var object_o = require('./objectcontrol.ts');
var private_fuc_module = require('./private_fuc.js');
var URL = (window.URL || window.webkitURL || window.msURL || window.oURL);
var AnyChatSDK = function (){
    var getway =  new webrtc.instance();
    var object_control = new object_o(getway);
    //判断是否支持webrtc
    if(!getway.support()){
        log('不支持webrtc');
        return false;
    }



    var _export = {};
    var exVideoArray = []; //存储视频设备
    var exAudioArray = []; //存储音频设备
    var videoStream = []; //视频流


    var private_fuc = private_fuc_module.instance(getway);
    /**
     *  数据标志
     *   CallBackFuc.OnNotifyMessage
     */


    var flag = {};
    flag.connect = false;
    /**
     *  说明
     *   CallBackFuc.OnNotifyMessage
     */
    var CallBackFuc = {};

    /**
     *  数据保存
     *  info.login;
     *  info.device_once 请求次数;
     *  info.dwStreamIndex 视频流 【】
     *  info.UserCameraControlExData 打开扩展摄像头数据缓存
     *  info.loginData 保存登录信息
     *  info.setvideoposData [];
     *  info.SetSDKOptionStringArr [];
     *  info.SetSDKOptionIntArr [];
     */
    var info = {};
    info.setvideoposData = [];
    info.SetSDKOptionStringArr = [];
    info.SetSDKOptionIntArr = [];



    //链接
    function Connect(lpServerAddr, dwPort)
    {
        var ip = lpServerAddr+':'+dwPort;
        var arr = [];
        arr.push(ip);
        info.addr = arr;
        getway.sessionid = null;
        getway.connect(arr);
    }


    //登录
    function Login(lpUserName, lpPassword, dwParam)
    {

        var data = {};
        data.username = lpUserName;
        data.password = lpPassword;
        data.passenctype = dwParam;

        if(data.username){
            getway.socket_send('request',0,'login',data);
        }

        //if(!flag.connect){
        //    info.loginData = {};
        //    info.loginData = data;
        //}else{
        //
        //}
    }

    //登录（扩展）
    function LoginEx(lpNickName,dwUserId, lpStrUserId, lpAppId, dwTimeStamp, lpSigStr, lpStrParam)
    {

        var data = {};
        data.nickname = lpNickName;
        data.userid = dwUserId;
        data.struserid = lpStrUserId;
        data.appId = lpAppId;
        data.timestamp = dwTimeStamp;
        data.lpSigStr = lpSigStr;
        data.lpStrParam = lpStrParam;
        getway.socket_send('request',0,'loginex',data);
    }


    //进房间
    function EnterRoom(dwRoomid, lpRoomPass, dwParam){

        var data = {};
        data.roomid = dwRoomid;
        data.roompass = lpRoomPass;
        data.passenctype = dwParam;

        if(getway.userid===-1){
            //还没有登录成功
            log('还没有登录成功，不能进房间');

            return false;
        }
        getway.socket_send('request',0,'enterroom',data);
    }


    //进房间（扩展）
    function EnterRoomEx(lpRoomName, lpRoomPass){
        var data = {};
        data.roomname = lpRoomName;
        data.roompass = lpRoomPass;
        data.passenctype = dwParam;

        getway.socket_send('request',0,'enterroomex',data);
    }


    //离开房间
    function leaveroom(roomid){
        var data = {};
        if(!getway.roomid){
            log('但不成功，因为没有进入房间');
            return 20;
        }
        private_fuc.closeAll(videoStream);
        roomid || (roomid=-1);
        data.roomid = roomid;
        getway.roomid = 0;
        getway.socket_send('request',0,'leaveroom',data);
    }

    //发送透明通道
    function TransBuffer(dwUserId,lpBuf)
    {
        var data = {};
        data.userid = dwUserId;
        data.buf = lpBuf;
        getway.socket_send('request',0,'transbuffer',data);
    }

    //注销
    function Logout(){
        var data = {};
        getway.socket_send('request',0,'logout',data);
    }


    // 视频呼叫事件控制（请求、回复、挂断等）
    function VideoCallControl(dwEventType, dwUserId, dwErrorCode, dwFlags, dwParam, szUserStr){
        var data = {};
        data.eventtype = dwEventType;
        data.userid = dwUserId;
        data.errorcode = dwErrorCode;
        data.flags = dwFlags;
        data.param = dwParam;
        data.userstr = szUserStr;
        getway.socket_send('request',0,'videocallcontrol',data);
    }

// 设置业务对象参数值
    function SetObjectStringValue(dwObjectType, dwObjectId, dwInfoName, value){
        var data = {};
        data.objecttype = dwObjectType;
        data.objectid = dwObjectId;
        data.infoname = dwInfoName;
        data.infovalue = value;
        data.valuetype = 1;// string
        getway.socket_send('request',0,'objectsetvalue',data);
    }
// 设置业务对象参数值
    function SetObjectIntValue(dwObjectType, dwObjectId, dwInfoName, value){
        var data = {};
        data.objecttype = dwObjectType;
        data.objectid = dwObjectId;
        data.infoname = dwInfoName;
        data.infovalue = value;
        data.valuetype = 0;//int
        getway.socket_send('request',0,'objectsetvalue',data);
    }

    //获取业务对象参数值
    function GetObjectIntValue(dwObjectType, dwObjectId, dwInfoName){
        var data = {};
        data.objecttype = dwObjectType;
        data.objectid = dwObjectId;
        data.infoname = dwInfoName;
        getway.socket_send('request',0,'objectgetvalue',data);
        return object_control.GetObjectIntValue(dwObjectType, dwObjectId, dwInfoName);
    }

    //获取业务对象参数值
    function GetObjectStringValue(dwObjectType, dwObjectId, dwInfoName){
        var data = {};
        data.objecttype = dwObjectType;
        data.objectid = dwObjectId;
        data.infoname = dwInfoName;
        getway.socket_send('request',0,'objectgetvalue',data);
        return object_control.GetObjectStringValue(dwObjectType, dwObjectId, dwInfoName);
    }


    //业务对象控制
    function ObjectControl(dwObjectType, dwObjectId, dwCtrlCode, dwParam1, dwParam2, dwParam3, dwParam4, strParam){
        var data = {};
        data.objecttype = dwObjectType;
        data.objectid = dwObjectId;
        data.ctrlcode = dwCtrlCode;
        data.param1 = dwParam1;
        data.param2 = dwParam2;
        data.param3 = dwParam3;
        data.param4 = dwParam4;
        data.strparam = strParam;
        getway.socket_send('request',0,'objectcontrol',data);
    }

    //获取业务对象ID列表（返回一个ObjectId的数组）
    function ObjectGetIdList(dwObjectType){
        var data = {};
        data.objecttype = dwObjectType;
        getway.socket_send('request',0,'objectgetidlist',data);
        return object_control.ObjectGetIdList(dwObjectType);
    }

    info.SetSDKOptionString = [];
    //系统全局设置字符串
    function SetSDKOptionString(optname,value){
        var data = {};
        data.optname = optname;
        data.optval = value;


        if(flag.connect){
            getway.socket_send('request',0,'setsdkoptionstring',data);
        }else{
            info.SetSDKOptionStringArr.push(data);
        }
    }


    info.SetSDKOptionInt = [] ;
    //系统全局设置整型
    function SetSDKOptionInt(optname,value){
        var data = {};
        data.optname = optname;
        data.optval = value;

        if(flag.connect){
            getway.socket_send('request',0,'setsdkoptionint',data);
        }else{
            info.SetSDKOptionIntArr.push(data);
        }
    }


    //获取sdkoption 值
    function GetSDKOptionString(optname){
        var data = {};
        data.optname = optname;
        getway.socket_send('request',0,'getsdkoptionstring',data);
    }

    //获取sdkoption 值
    function GetSDKOptionInt(optname){
        var data = {};
        data.optname = optname;
        getway.socket_send('request',0,'getsdkoptionint',data);
    }



    // 操作本地用户视频（或请求远程用户视频）
    function UserCameraControl(dwUserId,bOpen){
        var data = {};
        data.userid = dwUserId;
        data.open = bOpen;
        //private_fuc.createStream(exVideoArray[0]);
        getway.socket_send('request',0,'usercameracontrol',data);
    }

    // 操作本地用户视频（或请求远程用户视频）扩展方法
    function UserCameraControlEx(dwUserId, bOpen, dwStreamIndex, dwFlags, szStrParam){
        if(!getway.roomid){log('还没有进入房间'); return false;}
        var data = {};
        data.userid = dwUserId;
        data.open = bOpen;
        data.streamindex = dwStreamIndex;
        data.flags = dwFlags;
        data.strparam = szStrParam;
        //打开摄像头流start
        var streamindex_video =  info.streamindex_video;
        var deviceName = '';
        var deviceObj;
        if(dwUserId==-1){
            //打开自己
            for(var i in streamindex_video){
                if(streamindex_video[i].dwStreamIndex == dwStreamIndex){
                    deviceName = streamindex_video[i].value;
                    deviceObj = streamindex_video[i];
                }
            }

            if(bOpen==0){
                //关闭自己摄像头
                private_fuc.closeMyCamera(videoStream);
            }else{
                var obj = ByDevicesNameGetObj(deviceName);
                private_fuc.createStream(obj,deviceObj);
            }
        }else{

            if(bOpen==0){
                //关闭对方
                var setvideopos_arr = info.setvideoposData;
                var pid = 0;
                for(var i in setvideopos_arr){
                    if(setvideopos_arr[i].userId==dwUserId && setvideopos_arr[i].streamIndex==dwStreamIndex){
                        pid = setvideopos_arr[i].peerId;
                    }
                }
                if(pid!=0){
                    private_fuc.closeOtherCamera(pid);
                }
            }else {
                //打开对方
                var peerId = getway.sessionid+'_'+dwUserId+'_'+dwStreamIndex;
                var setvideoData = {};
                setvideoData.peerId = peerId;
                setvideoData.userId = dwUserId;
                setvideoData.streamIndex = dwStreamIndex;
                info.setvideoposData.push(setvideoData);
                //peerconnection
                getway.createPeerConnection(peerId);
                getway.addStreams(peerId);
            }

        }
        //打开摄像头流index

        //var int = setInterval(function(){
        //    if(info.offer){
        //        data.jsonbuf = info.offer;
        //        info.offer = '';
        //        clearInterval(int);
        //        getway.socket_send('request',0,'usercameracontrolex',data);
        //    }
        //},500);

        getway.socket_send('request',0,'usercameracontrolex',data);
    }

    // 操作本地用户语音（或请求远程用户语音）
    function UserSpeakControl(dwUserId, bOpen){
        var data = {};
        data.userid = dwUserId;
        data.open = bOpen;
        getway.socket_send('request',0,'userspeakcontrol',data);
    }


    //发送文字信息
    function SendTextMessage(dwUserId, bSecret, lpMsgBuf,parm){
        var data = {};
        data.userid = dwUserId;
        data.secret = bSecret;
        data.buf =  private_fuc.base64encode(lpMsgBuf);
        getway.socket_send('request',0,'sendtextmessage',data);
    }


    // 枚举设备的数量
    function PrepareFetchDevices(dwDeviceType){
        info.device_once = 0;
        if(dwDeviceType == 1){
            return exVideoArray.length;
        }else if(dwDeviceType == 2){
            return exAudioArray.length;
        }
    }



    // 返回设备的名称
    function FetchNextDevice(dwDeviceType){
        if(dwDeviceType==1){
            var obj = exVideoArray[info.device_once++];
            return obj.label;
        }
    }

    // 设置流
    info.streamindex_video = [];
    function SetUserStreamInfoString(dwUserId, dwStreamIndex, infoname, value){
        info.streamindex_video = private_fuc.strema_video(info,dwStreamIndex,infoname,value);
    }


    //获取房间用户列表数组
    function GetRoomOnlineUsers(index){
        if(index==-1){
            return getway.userlist;
        }
    }






    // 通过设备名返回设备obj
    function ByDevicesNameGetObj(DevicesName){
        for(var i in exVideoArray){
            if(exVideoArray[i].label == DevicesName) return exVideoArray[i]
        }
    }


// 设置视频显示位置
    function SetVideoPos(userid, parentobj, id){
        if(!getway.roomid){log('还没有进入房间'); return false;}
        if(userid==-1 || getway.userid == userid){
            //return false;
            var newVideo = document.createElement("video");
            var videos = parentobj;
            newVideo.setAttribute("class", "my");
            newVideo.setAttribute("autoplay", "autoplay");
            newVideo.setAttribute("id", id);
            videos.appendChild(newVideo);
            console.log('初始化显示流');
            var int = setInterval(function(){
                if(videoStream[0]){
                    console.log('显示流');
                    getway.attachStream(videoStream[0], id);
                    clearInterval(int);
                }
            },500)
        }else{


        }
        var i  = getVideoPosData(userid);
        if(i==-1)return false;
        info.setvideoposData[i].parentobj = parentobj;
        info.setvideoposData[i].id = id;

        function getVideoPosData(userid){
            var arr = info.setvideoposData;
            for(var i in arr){
                if(arr[i].userId == userid){

                }
            }
            if(i){
                return i;
            }else{
                return -1;
            }

        }
    }



    //OnAnyChatNotifyMessage
    var cmdType = {
        "connect":WM_GV_CONNECT,
        "login":WM_GV_LOGINSYSTEM,
        "enterroom":WM_GV_ENTERROOM,
        "onlineuser":WM_GV_ONLINEUSER,
        "linkclose":WM_GV_LINKCLOSE,
        "useratroom":WM_GV_USERATROOM
    };

    /**
     * 获取设备
     */
    function initDevices(){
        exVideoArray = [];
        exAudioArray = [];
        if (typeof MediaStreamTrack.getSources !== 'undefined')
        {
            MediaStreamTrack.getSources(gotSources);
        }
        function gotSources(sourceInfos) {
            for (var i = 0; i != sourceInfos.length; ++i) {
                var sourceInfo = sourceInfos[i];
                //这里会遍历audio,video，所以要加以区分
                if (sourceInfo.kind === 'video') {
                    exVideoArray.push(sourceInfo);
                }else if(sourceInfo.kind === 'audio'){
                    exAudioArray.push(sourceInfo);
                }
            }
        }
    }

    /**
     * 网关回调事件
     */
    function event(){
        //链接响应 reply
        getway.on("reply", function(data) {
            var json = data.data,
                cmdcode = json.cmdcode,
                errorcode = json.errorcode,
                wParam = '',
                lParam='';
            //OnAnyChatNotifyMessage
            if(cmdType[cmdcode]){
                switch(cmdcode){
                    case "connect":
                        if(info.loginData){
                            var data = {};
                            data = info.loginData;
                            if(data.username){
                                getway.socket_send('request',0,'login',data);
                            }
                        }
                        heartbeat_module.start(getway);
                        if(errorcode==0){
                            flag.connect = true;
                            private_fuc.SetSDKOptionString(info.SetSDKOptionStringArr);
                            private_fuc.SetSDKOptionInt(info.SetSDKOptionIntArr);
                            info.SetSDKOptionStringArr = [];
                            info.SetSDKOptionIntArr = [];
                        }
                        break;
                    case "login":
                        info.loginData = {};
                        if(errorcode==0){
                            getway.sessionid = json.sessionid;
                            getway.userid  = wParam = json.userid;
                        }else{
                            wParam = -1;
                        }
                        break;
                    case "enterroom":
                        if(errorcode==0)   getway.roomid = json.roomid;
                        wParam = json.roomid;
                        break;
                }
                cmdType[cmdcode] && CallBackFuc.OnNotifyMessage(cmdType[cmdcode],wParam,(lParam || errorcode));
            }


            //重连
            if(cmdcode==="tokenconnect"){
                if(errorcode==0){
                    log('重连成功');
                }else{
                    getway.sessionid = null;
                    log('重连失败');
                }

            }

            //心跳
            if(cmdcode==="heartbeat"){
                heartbeat_module.notify(errorcode);
            }


            //注销
            if(cmdcode==='logout'){
                log('注销成功');
                getway.socket.close();
                private_fuc.closeAll(videoStream);
                getway.roomid = 0;
                getway.userid = 0;
                getway.socket = null;
                getway.normalCloseWebsocket = true;
            }

        });


        //notify
        getway.on("notify",function(data){
            var json = data.data,
                cmdcode = json.cmdcode,
                errorcode = json.errorcode,
                wParam = '',
                lParam='';
            if(cmdType[cmdcode]){
                switch(cmdcode){
                    case "onlineuser":
                        var useridlist = json.useridlist;
                        if(typeof useridlist !== "object"){
                            useridlist = JSON.parse(useridlist);
                        }
                        var arr = useridlist.useridlist;
                        getway.userlist = arr;
                        getway.userlist.push(getway.userid);
                        wParam = arr.length;
                        lParam = json.roomid;
                        break;
                    case "linkclose":

                        break;
                    case "useratroom":
                        wParam = json.userid;
                        lParam = json.enter;
                        break;

                }
                cmdType[cmdcode] && CallBackFuc.OnNotifyMessage(cmdType[cmdcode],wParam,(lParam || errorcode));
            }



            //webrtc
            if(cmdcode === 'webrtcconsult'){
                if(errorcode==0){
                    var jsonbuf = JSON.parse(json.jsonbuf);
                    if(jsonbuf.type==='answer'){
                        log('收到answer');
                        getway.receiveAnswer(jsonbuf.peerconnectionid,jsonbuf.sdp);
                    }else if(jsonbuf.type==='candidate'){
                        log('收到candidate');
                        getway.candidate(jsonbuf);
                    }
                }
            }

            //文本信息通知
            if(cmdcode === 'sendtextmessage'){
                var buf = private_fuc.base64decode(json.buf);
                CallBackFuc.OnAnyChatTextMessage(json.fromuserid,json.touserid,json.secret,buf,0);
            }


            //对象通知objectcontrol
            if(cmdcode === 'objectevent'){
                if(json.eventtype == 0){
                    object_control.setObjectInfo(json);
                }else if(json.eventtype == -1){
                    object_control.setObjectInfo_1(json);
                }else{
                    CallBackFuc.OnAnyChatObjectEvent(json.objecttype,json.objectid,json.eventtype,json.param1,json.param2,json.param3,json.param4,json.strparam);
                }

            }

            //呼叫通知
            if(cmdcode === 'videocallevent'){
                // OnAnyChatVideoCallEvent(dwEventType, dwUserId, dwErrorCode, dwFlags,dwParam, szUserStr)
                CallBackFuc.OnAnyChatVideoCallEvent(json.eventtype,json.userid,json.errorcode,json.flags,json.param1,json.jsonbuf);
            }
        });


        getway.on("stream_created",function(stream){
           videoStream[0] = stream;
        });



        /**
         * 网络关闭
         */
        getway.on("close_websocket",function(data){
            console.log('执行重连');
            private_fuc.tokenconnect(info.addr);
        });


        /**
         * offer 发送
         */
        getway.on('offer',function(jsonBuf,peerconnectionid){
            var data = {};
            var obj = {};
            obj.type = "offer";
            obj.sdp = jsonBuf.sdp;
            obj.peerconnectionid = peerconnectionid;
            data.jsonbuf = obj;
            //data.peerconnectionid = jsonBuf.peerconnectionid;
            getway.socket_send('request',0,'webrtcconsult',data);
        });


        /**
         * 打开对方摄像头
         */
        getway.on('pc_add_stream',function(stream, sessionid){
            log('打开对方流：sessionid：'+sessionid);
            var info_ = info.setvideoposData,data;
            for(var i in info_){
                if(info_[i].peerId==sessionid){
                    data = info_[i];
                }
            }
            if(data){
                var newVideo = document.createElement("video"), id = data.id;
                var videos = data.parentobj;
                if(data.parentobj){
                    newVideo.setAttribute("class", "other");
                    newVideo.setAttribute('name',sessionid);
                    newVideo.setAttribute("autoplay", "autoplay");
                    newVideo.setAttribute("id", id);
                    videos.appendChild(newVideo);
                    getway.attachStream(stream, id);
                }
            }
        })
    }


    /**
     * 应用层事件绑定
     * @param cmdcode
     * @param fuc
     */
    function on(cmdcode,fuc){
        switch (cmdcode){
            case "OnNotifyMessage":
                CallBackFuc.OnNotifyMessage = fuc;
                break;
            case "OnVideoCallEvent":
                CallBackFuc.OnAnyChatVideoCallEvent = fuc;
                break;
            case "OnObjectEvent":
                CallBackFuc.OnAnyChatObjectEvent = fuc;
                break;
            case "OnTextMessage":
                CallBackFuc.OnAnyChatTextMessage = fuc;
                break;
        }

    }

    /**
     * 初始化一进来就执行
     */
    function init(){
        getway.browserName = private_fuc.getBrowser();
        console.log('浏览器名字：'+getway.browserName);
        //事件绑定
        event();
        //初始化设备
        initDevices();
    }
    init();
    _export.Connect = Connect;//链接
    _export.Login = Login;//登录
    _export.LoginEx = LoginEx;//登录扩展
    _export.EnterRoom = EnterRoom;//进入房间
    _export.EnterRoomEx = EnterRoomEx;//进入房间扩展
    _export.LeaveRoom = leaveroom;//离开房间
    _export.Logout = Logout;//注销
    _export.on = on;
    _export.UserCameraControl = UserCameraControl; //摄像头控制
    _export.UserCameraControlEx = UserCameraControlEx; //摄像头控制扩展
    _export.UserSpeakControl = UserSpeakControl; //麦克风控制
    _export.PrepareFetchDevices = PrepareFetchDevices; //枚举设备数量
    _export.FetchNextDevice = FetchNextDevice; //枚举设备数量
    _export.SetVideoPos = SetVideoPos;// 设置视频显示位置
    _export.SetUserStreamInfoString = SetUserStreamInfoString; //设置视频
    _export.SetSDKOptionString = SetSDKOptionString;//系统全局设置
    _export.SetSDKOptionInt = SetSDKOptionInt;//系统全局设置
    _export.VideoCallControl = VideoCallControl;//呼叫
    _export.SetObjectStringValue = SetObjectStringValue;//设置业务对象信息
    _export.SetObjectIntValue = SetObjectIntValue;//设置业务对象信息
    _export.GetObjectIntValue = GetObjectIntValue;//获取业务对象参数值
    _export.GetObjectStringValue = GetObjectStringValue;//获取业务对象参数值
    _export.ObjectControl = ObjectControl;// 业务对象控制指令
    _export.ObjectGetIdList = ObjectGetIdList;//获取业务对象ID列表（返回一个ObjectId的数组）
    _export.GetRoomOnlineUsers = GetRoomOnlineUsers;//获取房间用户列表数组
    _export.SendTextMessage = SendTextMessage;//发送文字信息
    _export.GetSDKOptionString = GetSDKOptionString; //获取sdkOption
    _export.GetSDKOptionInt = GetSDKOptionInt; //获取sdkOption
    _export.TransBuffer = TransBuffer;//发送透明通道
    return _export;
};

exports.instance = AnyChatSDK;
